import { LGXEnums } from "../../../../canvas/common/sysenum";
import lgxcom from "../../../../canvas/common/common";
import fillinfo from "../../../../canvas/common/struct/fillinfo";
const splitMarkCh = ',';

class AbsSvgUnitParser {
    constructor() {
        this.type = 0;
        this.symbolUnitFlag = false;
        this.svgHeight = 1200;
    }
    parse(mainEle) {

    }

    parseCommonProp(unitInfo, mainEle) {
        const attributes = mainEle.attributes;
        for (let i = 0; i < attributes.length; i++) {
            const attr = attributes[i];
            if (attr.name == 'fill') {
                this.parseFillProp(unitInfo, attr.value);
            }
            else if (attr.name == 'stroke') {
                unitInfo.color = this.chg2RGBValue(attr.value);
            }
            else if (attr.name == 'stroke-width') {
                unitInfo.lineWidth = parseFloat(attr.value);
            }
            else if (attr.name == 'class') {
                this.parseGraphPropRefClass(unitInfo, attr.value);
            }
        }
    }

    //<path id="path6681" d="m410-42l-24 1178-468-24 16-1170 476 16z" 
    //fill-rule="evenodd" stroke="#ff0202" stroke-width="0.4" fill="url(#linearGradient4795)"/>
    parseFillProp(unitInfo, propVal) {
        if (propVal == 'none'){
            return ;
        }
        unitInfo.fillInfo = new fillinfo.LGXFillDefInfo();
        if (propVal.indexOf('url') >= 0){
            //complex fill mode
            unitInfo.fillMode = propVal;
        }
        else{
            //solid fill
            unitInfo.fillMode = LGXEnums.LGXFillStyle.SOLID;
            unitInfo.fillInfo.fillColor.setColorByValue(this.chg2RGBValue(propVal));
        }
    }

    chg2RGBValue(svgColorVal) {
        let color = new lgxcom.LGXColor();
        svgColorVal = svgColorVal.toUpperCase();
        if (svgColorVal.indexOf('RGB') >=0 ){
            color.setByRGBString(svgColorVal);
        }
        else if (svgColorVal.indexOf('#') >= 0){
            color.setByHexString(svgColorVal);
        }
        return color.toValue();
    }

    parseGraphPropRefClass(unitInfo, classDefs) {
        unitInfo.color = 255;
    }

    transform2SystemCoord(point, transformStr) {
        let destPt = { x: point.x, y: point.y };
        let transStack = this.getTransformStack(transformStr);
        console.log(transStack);

        let scale = {sx:1,sy:1};
        let rot = {angle:0};

        for (let i = transStack.length - 1; i >= 0; i--) {
            let transformInfo = transStack[i];
            this.transformPosition(destPt, transformInfo,scale,rot);
        }
        return {pt:destPt,scale,rot};
    }

    transformPosition(destPt, transformInfo,scale,rot) {
        switch (transformInfo.type) {
            case 'translate':
                this.translatePoint(destPt, transformInfo.param);
                break;

            case 'rotate':
                this.rotatePoint(destPt, transformInfo.param,rot);
                break;

            case 'scale':
                this.scalePoint(destPt, transformInfo.param,scale);
                break;
        }
    }

    translatePoint(destPt, param) {
        destPt.x += param.x;
        destPt.y += param.y;
    }

    rotatePoint(destPt, param,rot) {
        if (param.angle == 0){
            return ;
        }
        let rotRadVal = Math.PI*param.angle/180;
        let detax = (destPt.x - param.x);
        let detay = (destPt.y - param.y);
        destPt.x = detax * Math.cos(rotRadVal) - detay * Math.sin(rotRadVal) + param.x;
        destPt.y = detax * Math.sin(rotRadVal) + detay * Math.cos(rotRadVal) + param.y;
        rot.angle += param.angle;
    }

    scalePoint(destPt, param,scale) {
        destPt.x *= param.x;
        destPt.y *= param.y;

        scale.sx *= param.x;
        scale.sy *= param.y;
    }


    getTransformStack(transformStr) {
        let stack = [];
        let list = transformStr.toUpperCase().split('');
        let chCount = transformStr.length;
        let idx = 0;
        do {
            let ch = list[idx];
            if (ch == 'R') {
                idx = this.parseRotate(idx, list, transformStr, stack);
            }
            else if (ch == 'T') {
                idx = this.parseTranslate(idx, list, transformStr, stack);
            }
            else if (ch == 'S') {
                idx = this.parseScale(idx, list, transformStr, stack);
            }

            idx++;
        }
        while (idx < chCount);
        return stack;
    }


    parseRotate(idx, list, transformStr, stack) {
        let endIdx = this.getSecEndIdx(idx, list);
        let tempStr = transformStr.substring(idx + 1, endIdx + 1);
        tempStr = tempStr.trim();

        let paramStIdx = tempStr.indexOf('(');
        let paramEndIdx = tempStr.indexOf(')');

        let paramStr = tempStr.substring(paramStIdx + 1, paramEndIdx);
        let paramList = paramStr.split(',');
        if (paramList.length != 3) {
            return endIdx;
        }

        let angle = parseFloat(paramList[0]);
        let x = parseFloat(paramList[1]);
        let y = parseFloat(paramList[2]);

        let t = { type: 'rotate', param: { x, y, angle } };
        stack.push(t);
        return endIdx;
    }

    parseScale(idx, list, transformStr, stack) {
        let endIdx = this.getSecEndIdx(idx, list);
        let tempStr = transformStr.substring(idx + 1, endIdx + 1);
        tempStr = tempStr.trim();

        let paramStIdx = tempStr.indexOf('(');
        let paramEndIdx = tempStr.indexOf(')');

        let paramStr = tempStr.substring(paramStIdx + 1, paramEndIdx);
        let paramList = paramStr.split(',');
        if (paramList.length != 2) {
            return endIdx;
        }

        let x = parseFloat(paramList[0]);
        let y = parseFloat(paramList[1]);

        let t = { type: 'scale', param: { x, y } };
        stack.push(t);
        return endIdx;
    }

    parseTranslate(idx, list, transformStr, stack) {
        let endIdx = this.getSecEndIdx(idx, list);
        let tempStr = transformStr.substring(idx + 1, endIdx + 1);
        tempStr = tempStr.trim();

        let paramStIdx = tempStr.indexOf('(');
        let paramEndIdx = tempStr.indexOf(')');

        let paramStr = tempStr.substring(paramStIdx + 1, paramEndIdx);
        let paramList = paramStr.split(',');
        if (paramList.length != 2) {
            return endIdx;
        }

        let x = parseFloat(paramList[0]);
        let y = parseFloat(paramList[1]);

        let t = { type: 'translate', param: { x, y } };
        stack.push(t);
        return endIdx;
    }


    getSecEndIdx(idx, list) {
        let dstIdx = list.length - 1;
        for (let i = idx + 1; i < list.length; i++) {
            let char = list[i];
            if (char == ')') {
                dstIdx = i;
                break;
            }
        }
        return dstIdx;
    }

    chg2SysCoord(point){
        if (this.symbolUnitFlag){
            point.y = -point.y;
        }
        else{
            point.y = this.svgHeight - point.y;
        }
    }

    convert2ValidPathCoordStr(coordStr){
        coordStr = coordStr.trim();
        coordStr = coordStr.replace(/ /g, splitMarkCh);
        coordStr = this.convert2ValidStr(coordStr);
        return coordStr;
    }
    
    //考虑到有些坐标值为负值时，之间没有空格也没有逗号
    convert2ValidStr(coordStr){
        coordStr = coordStr.trim();
        let validStr = '';
        let list = coordStr.split('');
        let chCount = coordStr.length;
        let idx = 1;
        validStr = list[0];
        do{
            let char = list[idx];
            if (char == '-'){
                let preChar = list[idx-1];
                if (preChar != ','){
                    validStr += ',';
                    validStr += char;
                }
            }
            else{
                validStr += char;
            }
            idx++;
        }
        while(idx < chCount);

        return validStr;
    }
}

export { AbsSvgUnitParser }